from datetime import datetime , timedelta 

from fastapi import APIRouter , Depends, HTTPException , UploadFile , File 
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm

from ..db.database import AsyncSession 
from ..dependencies import get_db_session 
from ..servies.user import UserServeries 
from ..servies.short import ShortServeries 
from ..utils.passlib_helper import PasslibHelper
from ..utils.auth_helper import AuthTokenHelper 
from ..utils.random_helper import generate_short_url
from ..schemas import SingleShortUrlCreate 



router_user = APIRouter(prefix='/api/v1', tags=['用户创建短链管理'])

oauth2_scheme = OAuth2PasswordBearer(tokenUrl='/api/v1/oauth2/authorize')



@router_user.post('/oauth2/authorize', summary='请求授权URL地址')
async def login(user_data: OAuth2PasswordRequestForm = Depends(), db_session:AsyncSession = Depends(get_db_session) ):
    """用户登录验证路由     

    Args:
        user_data (OAuth2PasswordRequestForm, optional): 这个是一个依赖会生成username,password表单字段
        db_session (AsyncSession, optional): 这是一个异步引擎， 执行异步查询（在数据库中查询用户）

    Raises:
        HTTPException: 如果输入用户名以及密码返回400错误
        HTTPException: 如果用户不存在返回401错误
        HTTPException: 如果用户密码不正确，返回400错误

    Returns:
        _type_: 返回生成的token值,以及token类型
    """
    if not user_data: 
        raise HTTPException(status_code=400, detail='请输入用户账号及密码等信息')
    
    userinfo = await UserServeries.get_user_by_name(db_session, user_data.username)
    if not userinfo: 
        raise HTTPException(status_code=401, detail='不存在此用户信息', headers={'WWW-Authenticate': 'Basic'})
    
    # 验证用户密码和哈希密码是否保持一致
    if not PasslibHelper.verity_password(user_data.password, userinfo.password): 
        raise HTTPException(status_code=400, detail='用户密码不对')

    # 签发JWT有效负载信息
    data = {
        'iss': userinfo.username,  # 签发者
        'sub': 'xiaozhongtongxue',  # 主题
        'username': userinfo.username, # 用户名
        'admin': True,  # 用户是否具有管理权限
        'exp': datetime.utcnow() + timedelta(minutes=15) # 过期时间
    }

    token = AuthTokenHelper.token_encode(data)

    return {'access_token': token, 'token_type': 'bearer'}



@router_user.post('/create/single/short', summary='创建单一短链请求')
async def create_single(creatinfo:SingleShortUrlCreate, token: str = Depends(oauth2_scheme),
                         db_session: AsyncSession = Depends(get_db_session) ): 
    payload = AuthTokenHelper.token_decode(token)
    username = payload.get('username')
    if username is None: 
        return 
    
    creatinfo.short_tag = generate_short_url()
    creatinfo.create_by = username 
    creatinfo.short_url = f'{creatinfo.short_url}{creatinfo.short_tag}'
    creatinfo.msg_context = f'{creatinfo.msg_context}, 欲了解详情，请单击{creatinfo.short_url}!'

    result = await ShortServeries.create_short_url(db_session, **creatinfo.model_dump())

    return {'code': 100, 'msg': '创建短链成功', 'data': {'short_url': result.short_url}}


@router_user.post('/create/batch/short', summary='通过文件方式批量创建短链')
async def create_batch(*, file: UploadFile = File(...), token: str = Depends(oauth2_scheme), 
                       db_session: AsyncSession = Depends(get_db_session)): 
    payload = AuthTokenHelper.token_decode(token=token)
    username = payload.get('username')
    if not username: 
        return 
    
    contents = await file.read()
    short_msg = contents.decode(encoding='utf-8').split('\n')

    def make_short_url(item: str): 
        split_item = item.split('#')
        short_tag = generate_short_url()
        short_url = f'http://127.0.0.1:8000/{short_tag}'

        return SingleShortUrlCreate(
            long_url=split_item[2], 
            short_tag = short_tag, 
            short_url= short_url, 
            create_by=username, 
            msg_context=f'{split_item[1].replace("chanename", split_item[0]).replace("url", "short_url")}'
        )
    
    result = await ShortServeries.create_batch_short_url(db_session, [make_short_url(item) for item in short_msg])
    
    return {'code': 200, 'msg': '批量创建短链成功', 'data': result}

